<template>
    <section>
        <!--工具条-->
        <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
            <el-form :inline="true" :model="filters">
                <el-form-item>
                    <el-input v-model="filters.keyword" placeholder="请输入编号或名称"></el-input>
                </el-form-item>
                <el-form-item>
                    <!-- 点击查询时 默认查第一页  因为带了条件之后不确定会有几页 -->
                    <el-button type="primary" v-on:click="handleCurrentChange(1)">查询</el-button>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="handleAdd">新增</el-button>
                </el-form-item>
            </el-form>
        </el-col>

        <!--列表-->
        <el-table ref="deptTable" :data="departments" highlight-current-row v-loading="listLoading" @select="selectRow" @select-all="selAll"   style="width: 100%;">
            <!-- 多选框的列 -->
            <el-table-column type="selection" width="55">
            </el-table-column>
            <el-table-column type="index" width="60">
            </el-table-column>
            <el-table-column prop="name" label="部门名称" width="120" sortable>
            </el-table-column>
            <el-table-column prop="sn" label="部门编号" width="120"  sortable>
            </el-table-column>
            <el-table-column prop="dirPath" label="层级路径" width="150" sortable>
            </el-table-column>
            <el-table-column prop="state" label="状态" width="120" sortable>
                <template scope="scope">
                    <span v-if="scope.row.state==0" style="color: green">启用</span>
                    <span v-else-if="scope.row.state==-1" style="color: red">禁用</span>
                    <span v-else>未知</span>
                </template>
            </el-table-column>
            <el-table-column prop="manager.username" label="部门经理" min-width="180" sortable>
            </el-table-column>
            <el-table-column prop="parent.name" label="上级部门" min-width="180" sortable>
            </el-table-column>
            <el-table-column label="操作" width="150">
                <template scope="scope">
                    <el-button size="small" @click="handleEdit(scope.row)">编辑</el-button>
                    <el-button type="danger" size="small" @click="handleDel(scope.row.id)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>

        <!--工具条-->
        <el-col :span="24" class="toolbar">
            <el-button type="danger" @click="batchRemove" v-perm="'dept:batchRemove'" :disabled="this.sels.length===0">批量删除</el-button>
            <!-- 分页栏
      @current-change="handleCurrentChange"   当前页发生变化 触发handleCurrentChange方法
      -->
            <el-pagination layout="prev, pager, next" @current-change="handleCurrentChange" :page-size="5" :total="total" style="float:right;">
            </el-pagination>
        </el-col>

        <!--新增界面-->
        <el-dialog :title="title" :visible.sync="addFormVisible" :close-on-click-modal="false">
            <el-form :model="addForm" label-width="80px" :rules="addFormRules" ref="addForm">
                <el-form-item label="部门编号" prop="sn">
                    <el-input v-model="addForm.sn" auto-complete="off"></el-input>
                </el-form-item>
                <el-form-item label="部门名称" prop="name">
                    <el-input v-model="addForm.name" auto-complete="off"></el-input>
                </el-form-item>
                <el-form-item label="状态">
                    <el-radio-group v-model="addForm.state">
                        <el-radio class="radio" :label="0">启用</el-radio>
                        <el-radio class="radio" :label="-1">禁用</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="部门经理">
                    <el-select v-model="addForm.manager.id" placeholder="请选择">
                        <el-option
                                v-for="item in employees"
                                :key="item.id"
                                :label="item.username"
                                :value="item.id">
                            <span style="float: left">{{ item.username }}</span>
                            <span style="float: right; color: #8492a6; font-size: 13px">{{ item.phone }}</span>
                        </el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="上级部门">
                    <el-cascader
                            @change="selChange"
                            v-model="addForm.parent.id"
                            :options="tree"
                            :props="{ checkStrictly: true, label: 'name', value: 'id' }"
                            clearable></el-cascader>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click.native="addFormVisible = false">取消</el-button>
                <el-button type="primary" @click.native="addSubmit" :loading="addLoading">提交</el-button>
            </div>
        </el-dialog>
    </section>
</template>

<script>
    export default {
        data() {
            return {
                /* 搜索的过滤条件 */
                filters: {
                    keyword: ''
                },
                currentPage: 1,  //当前页

                /* 列表绑定的数据  */
                departments: [],
                /* 总记录数 */
                total: 0,

                listLoading: false,  /* 加载状态 */

                sels: [],//列表选中列    用于批量删除

                /* 员工集合 */
                employees: [],
                /* 无限极部门树菜单 */
                tree: [],

                title: '新增',
                addFormVisible: false,//新增界面是否显示
                addLoading: false, //忙等状态
                addFormRules: {  //表单校验
                    name: [
                        { required: true, message: '请输入部门名称', trigger: 'blur' }
                    ],
                    sn: [
                        { required: true, message: '请输入部门编号', trigger: 'blur' }
                    ]
                },
                //新增界面数据
                addForm: {
                    sn: '', //部门编号
                    name: '', //部门名称
                    dirPath: '' ,//层级路径  不是用户输入的   是选择上级部门之后  自动拼接的
                    state: -1, //启用  禁用状态
                    manager: {}, //部门经理   添加时需要提交部门经理的id值
                    parent: {
                        id : []
                    }  //父级部门    添加时需要提交父级部门的id值
                }


            }
        },
        methods: {
            /* 全选按钮选中时触发 */
            selAll(selection){
                console.log('触发全选------',selection)
                for(let i = 0;i<selection.length;i++){
                    let currentDept = selection[i];
                    //判断是否存在子部门
                    this.selectRow(selection,currentDept);
                }
                console.log('---------最终选中项-----------',this.sels)
            },
            /* 部门切换选择时触发 */
            selChange(selNode){
                console.log('选中节点-----',selNode)
                console.log('当前正在编辑的节点----',this.addForm)
                //将选中的数组 放到全局 data中
                this.selNode = selNode;

            },

            //显示编辑界面
            handleEdit: function (rowData) {
                this.title = "编辑";
                console.log('-----handleEdit------',JSON.stringify(rowData));
                //显示对话框
                this.addFormVisible = true;
                //将行数据复制给row对象
                let row = Object.assign({},rowData);

                //判断是否有父级部门和经理  没有的话给个空对象， 否则取值会报错
                if(!row.parent){
                    row.parent = {id:[]}
                }

                if(!row.manager){
                    row.manager = {}
                }

                // //数据回显使用  dirPath拆分
                if(row.dirPath){
                    let arr = row.dirPath.substr(1).split("/");
                    console.log('拆分的数组-----',arr)
                    if(arr.length>0){
                        row.parent = {id:arr.slice(0,arr.length-1).map(item=>parseInt(item))};
                    }
                }

                console.log('回显数据----',JSON.stringify(row));

                //row就是当前行的实体对象  复制该对象  并赋值给addForm  addForm和表单做了双向数据绑定
                this.addForm = Object.assign({}, row);

            },
            //显示新增界面
            handleAdd: function () {

                this.addFormVisible = true;
                //新增更新数据
                this.addForm = {
                    sn: '', //部门编号
                    name: '', //部门名称
                    // dirPath: '' ,//层级路径  不是用户输入的   是选择上级部门之后  自动拼接的
                    state: -1, //启用  禁用状态
                    manager: {}, //部门经理   添加时需要提交部门经理的id值
                    parent: {id: []}  //父级部门    添加时需要提交父级部门的id值
                };
            },

            //删除
            handleDel: function (id) {
                console.log('要删除的id是---',id);
                //判断要删除的部门有没有子级部门   也就是通过parent_id来进行查询
                this.$http.get('/dept/pid/'+id).then(res=>{
                    console.log(res.data);
                    //如果存在子部门
                    if(res.data.length){
                        this.$message({
                            message: '该部门存在子部门，不能直接删除',
                            type: 'warning'
                        });
                    }else{
                        //没有子部门   询问   并删除
                        this.$confirm('确认删除该记录吗?', '提示', {
                            type: 'warning'
                        }).then(() => {
                            this.listLoading = true;
                            this.$http.delete('/dept/'+id).then((res) => {
                                this.listLoading = false;
                                let ajaxResult = res.data;
                                if(ajaxResult.success){
                                    this.$message({
                                        message: '删除成功',
                                        type: 'success'
                                    });
                                }else{
                                    this.$message({
                                        message: ajaxResult.message,
                                        type: 'error'
                                    });
                                }

                                this.handleCurrentChange(1); //删除刷新第一页
                            });
                        }).catch(() => {

                        });
                    }
                })
            },

            //************************新增和修改的方法*******************************
            addSubmit: function () {
                //表单校验   this.$refs.addForm  ----》 因为表单上 用了 ref='addForm'
                this.$refs.addForm.validate((valid) => {
                    //如果选的是当前节点
                    for(let i = 0;i<this.selNode.length;i++){
                        if(this.selNode[i]==this.addForm.id){
                            this.$message({
                                message: '上级部门不能选择自己或自己的子级部门',
                                type: 'warning'
                            });
                            valid = false;
                        }
                    }

                    //判断通过校验
                    if (valid) {

                        //询问是否需要进行提交
                        this.$confirm('确认提交吗？', '提示', {}).then(() => {
                            // this.addLoading = true; //开启忙等
                            //收集参数   将表单绑定的数据 复制到另一个对象中  作为备用参数
                            let para = Object.assign({}, this.addForm);

                            //查看备用参数
                            console.log('添加或修改之前收集的参数----',JSON.stringify(para));



                            //整理数据   parent: {id: [2,5]}      parent: {id: 5}
                            //修改时回显的数据 parent:{id:67}  不进行任何操作
                            let idArr = para.parent.id;
                            console.log('idArr----',idArr)
                            if(idArr.length>0){
                                //取出数组最后一项  最后一项是直接父级部门的id
                                para.parent.id = idArr[idArr.length-1]
                                //拼接dirPath 拼接父级部门路径
                                para.dirPath = '/' + idArr.join("/");   //[2,5]    /2/5   拼接的dirPath中只有父级  没有自己
                            }else if(idArr.length == 0){
                                //没有上级部门
                                para.parent = {}
                                para.dirPath = ''
                            }

                            // console.log('整理好之后的参数----',JSON.stringify(para));
                            /*
                            将部门的层级路径整理进去
                              假设去添加  /2/5/自己的id    添加时不知道自己的id   需要完成添加 返回自增id
                              第一步： 选择自己的上级部门  假设 /2/5
                              第二步： 将/2/5作为dirPath提交给服务器
                              第三步： 服务端完成添加   将/2/5作为dirPath添加到数据库    但是dirPath缺少自己的id    返回自增id   假设是67
                              第四步： 拿到自增id67    将它拼接到之前的/2/5/67
                              第五步： 发起修改  67   /2/5/67

                               假设去修改
                               第一步： 选择自己的上级部门  假设 /2/5
                               第二步： 将/2/5作为dirPath提交给服务器   同时携带了id
                               第三步： 服务端拿到dirPath  拼接自己的id  /2/5/67
                               第四步： 发起修改
                             */
                            //整理父级部门路径 添加到para参数中 提交即可


                            //查看整理的是否ok
                            console.log('整理之后----',para);

                            //判断是添加还是修改  添加和修改在服务端已经合并  是同一个接口

                            this.$http.put('/dept',para).then((res) => {
                                //关闭忙等
                                this.addLoading = false;
                                //成功提示
                                this.$message({
                                    message: '提交成功',
                                    type: 'success'
                                });
                                //重置表单
                                // this.$refs['addForm'].resetFields();
                                //隐藏添加的对话框
                                this.addFormVisible = false;
                                //重新查询列表更新页面   刷新到第一页
                                if(this.title=='新增'){
                                    this.handleCurrentChange(1);
                                }else if(this.title=='编辑'){
                                    this.getDepartments();
                                }

                            });
                        });
                    }
                });
            },

            //选中某一行  会触发该方法
            selectRow(selection, row){
                //selection  所有选中行对象的数组   row 当前选中行对象
                console.log('选中某行----',selection,row)

                //将selection  赋值给  data中的sels集合
                this.sels = selection;

                //拿着当前行的id去查询是否存在子部门
                this.$http.get('/dept/pid/'+row.id).then(res=>{
                    console.log(res.data);
                    //如果存在子部门
                    if(res.data.length){
                        this.$message({
                            message: '该部门存在子部门，不能直接删除',
                            type: 'warning'
                        });

                        //取消选中状态   选中table   toggleRowSelection
                        this.$refs.deptTable.toggleRowSelection(row,false);
                    }
                })

            },
            //批量删除
            batchRemove: function () {
                console.log('批量删除----',this.sels)
                var ids = this.sels.map(item => item.id);
                console.log('遍历集合，收集id--',ids);

                this.$confirm('确认删除选中记录吗？', '提示', {
                    type: 'warning'
                }).then(() => {
                    this.listLoading = true;
                    this.$http.patch('/dept',ids).then((res) => {
                        this.listLoading = false;

                        this.$message({
                            message: '删除成功',
                            type: 'success'
                        });
                        this.handleCurrentChange(1);
                    });
                }).catch(() => {

                });
            },

            //****************获取部门列表************************
            getDepartments() {
                //准备请求参数
                let para = {
                    currentPage: this.currentPage,  //当前页
                    keyword: this.filters.keyword  //搜索的关键词  可能是编号  也可能是名称
                };

                this.listLoading = true;  //开启忙等   也就是转圈的效果

                //发送分页查询请求
                this.$http.post('/dept',para).then((res) => {

                    console.log(res);

                    //更新表格数据
                    this.departments = res.data.rows

                    //更新分页的总记录
                    this.total = res.data.totals

                    this.listLoading = false; //关闭忙等
                });
            },
            /* *********************处理当前页切换************************ */
            handleCurrentChange(cPage) {
                console.log('handleCurrentChange-----',cPage);
                //更新当前页，因为data中的currentPage默认是1
                this.currentPage = cPage;
                //发起分页查询
                this.getDepartments();

            },
            /* 查询员工的方法 */
            getEmployees(){
                this.$http.get('/emp').then(res=>{
                    console.log(res.data);
                    //将查询到的员工集合赋值给data中的employees
                    this.employees = res.data;
                }).catch(res=>{

                })
            },

            /* 查询树结构 */
            getTree(){
                this.$http.get('/dept/tree').then(res=>{
                    console.log(res.data);
                    //给data中的tree赋值
                    this.tree = res.data;
                }).catch(res=>{

                })
            }
        },
        /* 挂载完毕的方法 */
        mounted() {
            //调用查询部门
            this.getDepartments();
            //调用查询员工的方法
            this.getEmployees();
            //调用查询部门树结构的方法
            this.getTree();
        }
    }

</script>

<style scoped>
</style>